//////////////////////////////////////////////////////////////////////////////////
//                                                                              //
//  This file is part of the buola project (https://code.google.com/p/buola/).  //
//                                                                              //
//  Copyright(c) 2007-2012 Xavi Gratal                                          //
//  gratal AT gmail DOT com                                                     //
//                                                                              //
//  Buola is free software: you can redistribute it and/or modify               //
//  it under the terms of the GNU General Public License as published by        //
//  the Free Software Foundation, either version 3 of the License, or           //
//  (at your option) any later version.                                         //
//                                                                              //
//  Buola is distributed in the hope that it will be useful,                    //
//  but WITHOUT ANY WARRANTY; without even the implied warranty of              //
//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the               //
//  GNU General Public License for more details.                                //
//                                                                              //
//  You should have received a copy of the GNU General Public License           //
//  along with buola.  If not, see <http://www.gnu.org/licenses/>.              //
//                                                                              //
//////////////////////////////////////////////////////////////////////////////////

#include <buola/buola.h>
#include <buola/zz/operators.h>
#include <buola/zz/zinteger.h>
#include <buola/zz/zchar.h>
#include <buola/zz/repeat.h>
#include <buola/zz/if.h>
#include <buola/functors/predicates/char.h>
#include <buola/io.h>

template<typename tClass,typename,typename... tArgs>
struct is_callable_impl
{
    static const bool value=false;
};

template<typename tClass,typename... tArgs>
//struct is_callable_impl<tClass,sizeof((*(tClass*(0)))(*(tArgs*(0))...))==0||true,tArgs...>
struct is_callable_impl<tClass,decltype((*(tClass*)(0))(1)),tArgs...>
{
    static const bool value=true;
};

template<typename a>
class dummy_template
{
public:
    typedef bool type;
};

template<typename tClass>
bool is_callable(unsigned int)
{
    return false;
}

template<typename tClass>
typename dummy_template<decltype((*(tClass*)(0))(1))>::type is_callable(int)
{
    return true;
}

template<typename tTonto>
void check_callable(const tTonto&)
{
    buola::msg_info() << is_callable_impl<tTonto,int>::value << "\n";
//    buola::msg_info() << is_callable<tTonto>::value << "\n";
}

int main()
{
    using namespace buola;
    
    typedef zz::ZChar<char> tC;
    typedef zz::ZInteger<int> tI;
    
    buola_init();
    
    start_timer();
    std::string lString("12345,23456,34567,45678,");
    for(int i=0;i<22;i++)
        lString+=lString;
    lString+="5.";
    for(int i=0;i<3;i++)
        lString+=lString;
    end_timer();
    
    std::vector<std::vector<int>> lInt;
    std::string::const_iterator lB=lString.begin(),lE=lString.end();
    
    start_timer();
    parse(lB,lE,(zz::ZInteger<int>()%zz::ZChar<char>(','))%zz::ZChar<char>('.'),lInt);
    end_timer();
    
    msg_info() << lInt.size() << "\n";
    for(int i=0;i<lInt.size();i++)
        msg_info() << lInt[i].size() << "\n";

    msg_info() << "trying repeat\n";

    std::string lString2("27 3 5 7 9");
    std::array<int,5> lArray;

    lB=lString2.begin(),lE=lString2.end();
    phrase_parse(lB,lE,zz::repeat<5>(zz::ZInteger<int>()),zz::if_true(fn::is_ascii_space()),lArray);

    for(int i : lArray)
        msg_info() << i << "\n";

    std::string lInput("42 0:1 1:2 2:2 3:1 4:1 5:3");
    int lCount;
    std::vector<std::pair<int,int>> lData;
    
    phrase_parse(lInput.begin(),lInput.end(),zz::ZInteger<int>() >> *(zz::ZInteger<int>() >> ~zz::chr(':') >> zz::ZInteger<int>()),
                zz::if_true(fn::is_ascii_space()),std::tie(lCount,lData));
    
    msg_info() << lCount << "," << lData.size() << "\n";
    msg_info() << lData[5].first << "," << lData[5].second << "\n";
    
    return buola_finish();
}
/*
int main()
{
    using namespace buola;

    buola_init();
    
    std::string lString("12345,12346,12347");
    
    std::tuple<int,char,int,char,int> lResult;
    std::string::const_iterator lB=lString.begin(),lE=lString.end();

    parse(lB,lE,(zz::ZInteger<int>()>>~zz::ZChar<char>(',')>>zz::ZInteger<int>()>>zz::ZChar<char>(',')>>zz::ZInteger<int>()),lResult);
    
    msg_info() << std::get<0>(lResult) << "\n";
    msg_info() << std::get<2>(lResult) << "\n";
    msg_info() << std::get<4>(lResult) << "\n";
    
    return buola_finish();
}
*/
